﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

using Seven.Core.IRepositories;
using Seven.Entity;
using Seven.EntityBasic;
using Seven.DataModel.ViewModels.MenuAbout;
using Seven.Service.Security;
using Seven.Tools.Extension;
using Seven.Tools.Helper;

namespace Seven.Service.Powerful
{
    public partial class SysMenuPermissionService
    {
        /// <summary>
        /// 根据用户ID获取该用户可用的的菜单权限数据集合
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="all">是否获取全部，默认否。若是，将忽略权限。</param>
        /// <returns></returns>
        public IEnumerable<SysMenuPermission> GetRangeMenuPermissions(int userId, bool all = false)
        {
            IEnumerable<SysMenuPermission> result = new List<SysMenuPermission>();
            IList<int> menuPermissionIDs = new List<int>();
            IList<SysUserMenuPermission> userPermissions;
            IEnumerable<SysRoleMenuPermission> rolePermissions;
            using (var unit = DbFactory.UnitOfWork)
            {
                if (all) { return unit.SysMenuPermission.GetAllMenuPermissions(); }
                else
                {
                    userPermissions = unit.SysUserMenuPermission.GetUserMenuPermissions(userId).ToList();

                    if (userPermissions.Count() == 0)
                    {
                        result = unit.SysRoleMenuPermission.GetRangeMenuPermissions(userId);
                        rolePermissions = new List<SysRoleMenuPermission>();
                    }
                    else
                    {
                        //获取不在用户权限表中记录过的菜单权限，当作“选中不打勾”状态处理
                        IEnumerable<int> temp = userPermissions.Select(s => s.MenuPermissionID);
                        var other = unit.SysMenuPermission.GetMenuPermissionsExcept(temp);
                        if (other.Count() > 0)
                        {
                            foreach (var item in other)
                            {
                                userPermissions.Add(new SysUserMenuPermission { UserID = userId, MenuPermissionID = item.ID, Check = true, Indeterminate = false });
                            }
                        }

                        rolePermissions = unit.SysRoleMenuPermission.GetRoleMenuPermissionsByUserID(userId);
                    }

                    if (userPermissions.Count() > 0)
                    {
                        #region 若用户权限不为空，则遍历用户权限集合，结合角色权限进行合并

                        foreach (var item in userPermissions)
                        {
                            if (item.Check && !item.Indeterminate)
                            {
                                //用户权限 打勾且选中
                                menuPermissionIDs.Add(item.MenuPermissionID);
                            }
                            else if (item.Check && item.Indeterminate)
                            {
                                //用户权限 打勾不选中
                                if (rolePermissions.Any(a => a.MenuPermissionID == item.MenuPermissionID && a.Check))
                                {
                                    menuPermissionIDs.Add(item.MenuPermissionID);
                                }
                            }
                        }
                        if (menuPermissionIDs.Count() > 0) { result = unit.SysMenuPermission.GetMenuPermissions(menuPermissionIDs); }

                        #endregion
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// 获取按钮权限数据集合
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <param name="all">是否获取全部，默认否。若是，将忽略权限。</param>
        /// <returns></returns>
        public IEnumerable<ButtonPermissionModel> GetButtonPermissions(int userid, bool all = false)
        {
            IEnumerable<SysMenuPermission> userable = this.GetRangeMenuPermissions(userid, all);
            return this.GetButtonPermissions(userable);
        }

        /// <summary>
        /// 获取按钮权限数据集合
        /// </summary>
        /// <param name="userableButtons">可用的按钮权限集合</param>
        /// <returns></returns>
        public IEnumerable<ButtonPermissionModel> GetButtonPermissions(IEnumerable<SysMenuPermission> userableButtons)
        {
            IEnumerable<SysMenuPermission> other; IList<ButtonPermissionModel> result = new List<ButtonPermissionModel>();
            using (var unit = DbFactory.UnitOfWork)
            {
                other = unit.SysMenuPermission.GetMenuButtonPermissionsExcept(userableButtons.Select(s => s.ID));
            }
            foreach (var item in userableButtons)
            {
                result.Add(new ButtonPermissionModel
                {
                    MenuID = item.MenuID,
                    ButtonName = item.ButtonName,
                    IconCls = string.IsNullOrWhiteSpace(item.IconCls) ? SiteCore.DefaultIconClassName : item.IconCls,
                    HandlerName = item.HandlerName,
                    GroupMark = item.GroupMark,
                    IsDisabled = false,
                    SortNumber = item.SortNumber
                });
            }
            foreach (var item in other)
            {
                result.Add(new ButtonPermissionModel
                {
                    MenuID = item.MenuID,
                    ButtonName = item.ButtonName,
                    IconCls = string.IsNullOrWhiteSpace(item.IconCls) ? SiteCore.DefaultIconClassName : item.IconCls,
                    HandlerName = item.HandlerName,
                    GroupMark = item.GroupMark,
                    IsDisabled = true,
                    SortNumber = item.SortNumber
                });
            }

            return result;
        }

        #region 获取ViewModel

        /// <summary>
        /// 获取新的菜单权限模型
        /// </summary>
        /// <param name="menuId">菜单ID</param>
        /// <param name="menuName">菜单名称，已解码过</param>
        /// <returns></returns>
        public MenuPermissionModel GetNewMenuPermissionModel(int menuId, string menuName)
        {
            var model = new MenuPermissionModel();
            model.MenuID = menuId;
            model.MenuName = menuName;
            model.Type = PermissionType.访问;
            model.IsShow = true;

            return model;
        }

        /// <summary>
        /// 根据菜单权限ID获取供编辑的数据模型
        /// </summary>
        /// <param name="id">菜单权限ID</param>
        /// <returns></returns>
        public MenuPermissionModel GetEditMenuPermissionModel(int id)
        {
            using (var unit = DbFactory.UnitOfWork)
            {
                return unit.SysMenuPermission.GetEditModelByID(id);
            }
        }

        #endregion

        #region 提供json数据

        /// <summary>
        /// 提供权限类型json数据
        /// </summary>
        /// <returns></returns>
        public JsonResult PermissionTypeJson()
        {
            var Types = EnumHelper.GetEnumItems<PermissionType>(typeof(PermissionType));

            return new DataResult(Types.Select(s => new { s.Value, s.Text })).SerializeToJsonResult();
        }

        /// <summary>
        /// 提供菜单权限json数据
        /// </summary>
        /// <param name="menuId">菜单ID</param>
        /// <returns></returns>
        public JsonResult MenuPermissionJson(int menuId)
        {
            IEnumerable<SysMenuPermission> data;

            using (var unit = DbFactory.UnitOfWork)
            {
                data = unit.SysMenuPermission.GetMenuPermissionsByMenuID(menuId);
            }

            return new DataResult(data.Select(s => new
            {
                s.ID,
                s.ButtonName,
                s.Name,
                Type = s.Type.ToString(),
                s.SortNumber,
                s.GroupMark,
                s.IconCls,
                s.IsShow,
                funcc = (s.Type == PermissionType.按钮 && !string.IsNullOrWhiteSpace(s.HandlerName)) ? true : false,
                multiple = (!string.IsNullOrWhiteSpace(s.FunctionIDs) && s.FunctionIDs.IndexOf(",") > -1)
            })).SerializeToJsonResult();
        }

        #endregion

        #region CUD操作

        /// <summary>
        /// 保存菜单权限
        /// </summary>
        /// <param name="model">菜单权限数据模型</param>
        /// <returns></returns>
        public JsonResult SaveMenuPermission(MenuPermissionModel model)
        {
            SysMenuPermission entity;
            if (model.ID == 0)
            {
                entity = model.CopyTo<SysMenuPermission>();
                if (entity.Type != PermissionType.按钮)
                {
                    entity.ButtonName = string.Empty;
                    entity.IconCls = string.Empty;
                    entity.HandlerName = string.Empty;
                }

                return this.Insert(entity).SerializeToJsonResult();
            }
            else
            {
                entity = this.GetByKey(model.ID);
                entity.Name = model.Name;
                entity.Type = model.Type;
                if (entity.Type == PermissionType.按钮)
                {
                    entity.ButtonName = model.ButtonName;
                    entity.IconCls = model.IconCls;
                    entity.HandlerName = model.HandlerName;
                }
                else
                {
                    entity.ButtonName = string.Empty;
                    entity.IconCls = string.Empty;
                    entity.HandlerName = string.Empty;
                }
                entity.GroupMark = model.GroupMark;
                entity.SortNumber = model.SortNumber;
                entity.FunctionIDs = model.FunctionIDs;
                entity.IsShow = model.IsShow;
                entity.Remark = model.Remark;

                return this.Update(entity).SerializeToJsonResult();
            }
        }

        /// <summary>
        /// 移除菜单权限
        /// </summary>
        /// <param name="id">菜单权限id</param>
        /// <returns></returns>
        public JsonResult RemoveMenuPermission(int id)
        {
            var entity = this.GetByKey(id);
            if (entity == null) { return new OperationResult(false, "菜单权限不存在！").SerializeToJsonResult(); }

            using (var unit = DbFactory.UnitOfWork)
            {
                var rep = unit.SysMenuPermission;

                try
                {
                    unit.BeginTransaction();
                    rep.EntityDeleted(entity);
                    unit.SysUserMenuPermission.EntitiesDeleted(d => d.MenuPermissionID == entity.ID);
                    unit.SysRoleMenuPermission.EntitiesDeleted(d => d.MenuPermissionID == entity.ID);
                    var msg = new string[] { "删除成功!", "删除失败!" };
                    return new OperationResult(unit.Commit() > 0, msg).SerializeToJsonResult();
                }
                catch (DataAccessException ex)
                {
                    unit.Rollback();
                    throw ExceptionHelper.ThrowServiceException(ex.Message);
                }
            }
        }

        #endregion
    }
}
